// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.core.skinnedmodel;

import java.nio.FloatBuffer;
import org.lwjglx.BufferUtils;

public class Matrix4 {
    private FloatBuffer matrix = FloatBuffer.allocate(16);
    public static Matrix4 Identity = new Matrix4();
    private FloatBuffer direct;

    public Matrix4() {
    }

    public Matrix4(float[] _float) {
        this();
        this.put(_float);
    }

    public Matrix4(Matrix4 m) {
        this();
        this.put(m);
    }

    public Matrix4 clear() {
        for (int _int = 0; _int < 16; _int++) {
            this.matrix.put(_int, 0.0F);
        }

        return this;
    }

    public Matrix4 clearToIdentity() {
        return this.clear().put(0, 1.0F).put(5, 1.0F).put(10, 1.0F).put(15, 1.0F);
    }

    public Matrix4 clearToOrtho(float left, float right, float bottom, float top, float near, float far) {
        return this.clear()
            .put(0, 2.0F / (right - left))
            .put(5, 2.0F / (top - bottom))
            .put(10, -2.0F / (far - near))
            .put(12, -(right + left) / (right - left))
            .put(13, -(top + bottom) / (top - bottom))
            .put(14, -(far + near) / (far - near))
            .put(15, 1.0F);
    }

    public Matrix4 clearToPerspective(float fovRad, float width, float height, float near, float far) {
        float _float = 1.0F / (float)Math.tan((double)(fovRad / 2.0F));
        return this.clear()
            .put(0, _float / (width / height))
            .put(5, _float)
            .put(10, (far + near) / (near - far))
            .put(14, 2.0F * far * near / (near - far))
            .put(11, -1.0F);
    }

    public float get(int index) {
        return this.matrix.get(index);
    }

    public Matrix4 put(int index, float f) {
        this.matrix.put(index, f);
        return this;
    }

    public Matrix4 put(int index, Vector3 v, float w) {
        this.put(index * 4 + 0, v.x());
        this.put(index * 4 + 1, v.y());
        this.put(index * 4 + 2, v.z());
        this.put(index * 4 + 3, w);
        return this;
    }

    public Matrix4 put(float[] _float) {
        if (_float.length < 16) {
            throw new IllegalArgumentException("float array must have at least 16 values.");
        } else {
            this.matrix.position(0);
            this.matrix.put(_float, 0, 16);
            return this;
        }
    }

    public Matrix4 put(Matrix4 m) {
        FloatBuffer floatBuffer = m.getBuffer();

        while (floatBuffer.hasRemaining()) {
            this.matrix.put(floatBuffer.get());
        }

        return this;
    }

    public Matrix4 mult(float[] float1) {
        float[] float0 = new float[16];

        for (byte _byte = 0; _byte < 16; _byte += 4) {
            float0[_byte + 0] = this.get(0) * float1[_byte]
                + this.get(4) * float1[_byte + 1]
                + this.get(8) * float1[_byte + 2]
                + this.get(12) * float1[_byte + 3];
            float0[_byte + 1] = this.get(1) * float1[_byte]
                + this.get(5) * float1[_byte + 1]
                + this.get(9) * float1[_byte + 2]
                + this.get(13) * float1[_byte + 3];
            float0[_byte + 2] = this.get(2) * float1[_byte]
                + this.get(6) * float1[_byte + 1]
                + this.get(10) * float1[_byte + 2]
                + this.get(14) * float1[_byte + 3];
            float0[_byte + 3] = this.get(3) * float1[_byte]
                + this.get(7) * float1[_byte + 1]
                + this.get(11) * float1[_byte + 2]
                + this.get(15) * float1[_byte + 3];
        }

        this.put(float0);
        return this;
    }

    public Matrix4 mult(Matrix4 m) {
        float[] _float = new float[16];

        for (byte _byte = 0; _byte < 16; _byte += 4) {
            _float[_byte + 0] = this.get(0) * m.get(_byte) + this.get(4) * m.get(_byte + 1) + this.get(8) * m.get(_byte + 2) + this.get(12) * m.get(_byte + 3);
            _float[_byte + 1] = this.get(1) * m.get(_byte) + this.get(5) * m.get(_byte + 1) + this.get(9) * m.get(_byte + 2) + this.get(13) * m.get(_byte + 3);
            _float[_byte + 2] = this.get(2) * m.get(_byte) + this.get(6) * m.get(_byte + 1) + this.get(10) * m.get(_byte + 2) + this.get(14) * m.get(_byte + 3);
            _float[_byte + 3] = this.get(3) * m.get(_byte) + this.get(7) * m.get(_byte + 1) + this.get(11) * m.get(_byte + 2) + this.get(15) * m.get(_byte + 3);
        }

        this.put(_float);
        return this;
    }

    public Matrix4 transpose() {
        float _float = this.get(1);
        this.put(1, this.get(4));
        this.put(4, _float);
        _float = this.get(2);
        this.put(2, this.get(8));
        this.put(8, _float);
        _float = this.get(3);
        this.put(3, this.get(12));
        this.put(12, _float);
        _float = this.get(7);
        this.put(7, this.get(13));
        this.put(13, _float);
        _float = this.get(11);
        this.put(11, this.get(14));
        this.put(14, _float);
        _float = this.get(6);
        this.put(6, this.get(9));
        this.put(9, _float);
        return this;
    }

    public Matrix4 translate(float x, float y, float z) {
        float[] _float = new float[16];
        _float[0] = 1.0F;
        _float[5] = 1.0F;
        _float[10] = 1.0F;
        _float[15] = 1.0F;
        _float[12] = x;
        _float[13] = y;
        _float[14] = z;
        return this.mult(_float);
    }

    public Matrix4 translate(Vector3 vec) {
        return this.translate(vec.x(), vec.y(), vec.z());
    }

    public Matrix4 scale(float x, float y, float z) {
        float[] _float = new float[16];
        _float[0] = x;
        _float[5] = y;
        _float[10] = z;
        _float[15] = 1.0F;
        return this.mult(_float);
    }

    public Matrix4 scale(Vector3 vec) {
        return this.scale(vec.x(), vec.y(), vec.z());
    }

    public Matrix4 rotate(float angle, float x, float y, float z) {
        float float0 = (float)Math.cos((double)angle);
        float float1 = (float)Math.sin((double)angle);
        float float2 = 1.0F - float0;
        Vector3 vector3 = new Vector3(x, y, z).normalize();
        float[] float3 = new float[16];
        float3[0] = vector3.x() * vector3.x() + (1.0F - vector3.x() * vector3.x()) * float0;
        float3[4] = vector3.x() * vector3.y() * float2 - vector3.z() * float1;
        float3[8] = vector3.x() * vector3.z() * float2 + vector3.y() * float1;
        float3[1] = vector3.y() * vector3.x() * float2 + vector3.z() * float1;
        float3[5] = vector3.y() * vector3.y() + (1.0F - vector3.y() * vector3.y()) * float0;
        float3[9] = vector3.y() * vector3.z() * float2 - vector3.x() * float1;
        float3[2] = vector3.z() * vector3.x() * float2 - vector3.y() * float1;
        float3[6] = vector3.z() * vector3.y() * float2 + vector3.x() * float1;
        float3[10] = vector3.z() * vector3.z() + (1.0F - vector3.z() * vector3.z()) * float0;
        float3[15] = 1.0F;
        return this.mult(float3);
    }

    public Matrix4 rotate(float angle, Vector3 vec) {
        return this.rotate(angle, vec.x(), vec.y(), vec.z());
    }

    public FloatBuffer getBuffer() {
        if (this.direct == null) {
            this.direct = BufferUtils.createFloatBuffer(16);
        }

        this.direct.clear();
        this.direct.put(this.matrix.position(16).flip());
        this.direct.flip();
        return this.direct;
    }

    static {
        Identity.clearToIdentity();
    }
}
